package com.hmkj.core.model.user;

import com.alibaba.fastjson.annotation.JSONField;
import com.hmkj.common.utils.ValidateUtils;
import com.hmkj.core.exception.BussinessException;
import com.hmkj.core.po.amount.Account;
import com.hmkj.core.po.operate.Agent;
import com.hmkj.core.po.user.User;
import com.xiaoleilu.hutool.crypto.SecureUtil;
import com.xiaoleilu.hutool.crypto.asymmetric.KeyType;
import com.xiaoleilu.hutool.crypto.asymmetric.RSA;
import com.xiaoleilu.hutool.crypto.digest.DigestUtil;
import com.xiaoleilu.hutool.lang.Base64;
import com.xiaoleilu.hutool.setting.dialect.Props;
import com.xiaoleilu.hutool.util.StrUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.math.BigDecimal;
import java.util.Date;
import java.util.function.Consumer;

@Data
@ApiModel(description = "用户表")
public class UserModel extends User {
    /**
     * 邀请人用户
     */
    private User p;

    /**
     *代理商
     */
    private Agent ag;

    /**
     * 用户账户
     */
    private Account a;

    private BigDecimal securityScore;


    /**
     * 交易手数
     */
    @ApiModelProperty(value = "交易手数")
    private Integer tradeNum;


    /**
     * 注册用户数量
     */
    @ApiModelProperty(value = "注册用户数量")
    private Long userNum;

    /**
     * 注册时间
     */
    @ApiModelProperty(value = "注册时间")
    @JSONField(format="yyyy-MM-dd")
    private Date registerTime;

    /**
     * 充值用户数量
     */
    @ApiModelProperty(value = "充值用户数量")
    private Long rechargeNum;

    /**
     * 总充值金额
     */
    @ApiModelProperty(value = "总充值金额")
    private BigDecimal totalAmo;

    /**
     * 注册-充值转化率
     */
    @ApiModelProperty(value = "注册-充值转化率")
    private BigDecimal scaleRec;
    /**
     * 人均充值金额
     */
    @ApiModelProperty(value = "人均充值金额")
    private BigDecimal averageAmo;
    /**
     * 隐藏部分手机号码
     */
    @ApiModelProperty(value = "部分隐藏的手机号")
    private String mobileHide;

    /**
     * 邀请人数
     */
    @ApiModelProperty(value = "邀请数量")
    private Long inviteNumber;

    /**
     * 贡献奖励
     */
    @ApiModelProperty(value = "贡献奖励")
    private BigDecimal inviteAmount;

    /**
     * 是否设置支付密码 0 未设置 1 已设置
     */
    private int hasPayPwd = 0;

    /**
     * 注册邀请码
     */
    private String i;

    public UserModel() {
    }

    public UserModel(Consumer<UserModel> consumer) {
        consumer.accept(this);
    }

    /**
     * 实名认证基础校验
     */
    public static void checkRealName(String realName,String idCard) {
        if (StrUtil.isBlank(realName)) {
            throw new BussinessException("真实姓名不能为空");
        }else if(realName.length()>20){
            throw new BussinessException("真实姓名长度不能大于20个字符");
        }
        if (StrUtil.isBlank(idCard)) {
            throw new BussinessException("身份证号码不能为空");
        }else if(idCard.length()<15 || idCard.length()>18){
            throw new BussinessException("身份证号码长度限制在15到18个字符");
        }else if(!ValidateUtils.isCard(idCard)){
            throw new BussinessException("身份证号码格式不正确");
        }
    }

    /**
     * 支付宝实名基础校验
     */
    public static void checkAlipayAccount(String alipayAccount) {
        if (StrUtil.isBlank(alipayAccount)) {
            throw new BussinessException("请填写支付宝账户");
        }else if(alipayAccount.length()>50 || alipayAccount.length()<2){
            throw new BussinessException("支付宝账户长度不能小于2个字符或大于50个字符");
        }else if(ValidateUtils.isContainChinese(alipayAccount)){
            throw new BussinessException("支付宝账户不能含有中文字符");
        }
    }

    /**
     * 注册基础校验
     */
    public void checkRegister() {
        if (StrUtil.isBlank(getMobile()))
            throw new BussinessException("手机号不能为空");
        if (StrUtil.isBlank(getPassword()))
            throw new BussinessException("密码不能为空");
    }

    /**
     * 注册基础校验
     */
    public void checkLogin() {
        if (StrUtil.isBlank(getMobile()))
            throw new BussinessException("手机号不能为空");
        if (StrUtil.isBlank(getPassword()))
            throw new BussinessException("密码不能为空");
    }

    /**
     * 登陆过期cookie加密串获得 <br> 格式:md5(userId+干扰符+登陆时间戳)_登陆时间戳 作cookie过期校验
     *
     * @param userId 用户id
     * @param md5Pwd md5密码
     * @return 加密串
     */
    public static String getLoginCookieVal(Integer userId, String md5Pwd) {
        String loginTime = System.currentTimeMillis() + "";
        return getLoginCookieVal(userId, md5Pwd, loginTime);
    }


    /**
     * 登陆过期cookie加密串获得 <br> 格式:md5(userId+干扰符+登陆时间戳)_登陆时间戳 作cookie过期校验
     *
     * @param userId   用户id
     * @param md5Pwd   md5密码
     * @param dataTime 时间戳
     * @return 加密串
     */
    public static String getLoginCookieVal(Integer userId, String md5Pwd, String dataTime) {
        return DigestUtil.md5Hex(userId + md5Pwd + dataTime) + "_" + dataTime;
    }

    /**
     * 解密前台传入登录密码(先base64解密再rsa解密)
     *
     * @return
     */
    public String decryptPwd() {
        try {
            Props props = new Props("rsa-key.properties");
            RSA rsa = SecureUtil.rsa(props.getProperty("privatekey"), props.getProperty("publickey"));
            String pwd = getPassword();
            // base64解密再rsa解密
            pwd = new String(rsa.decrypt(Base64.decode(pwd), KeyType.PrivateKey));
            return pwd;
        } catch (Exception e) {
            e.printStackTrace();
            throw new BussinessException("密码解析失败");
        }
    }

    /**
     * 密码加密(用于保存)
     *
     * @param pwd
     * @return
     */
    public static String encodePwd(String pwd) {
        return DigestUtil.md5Hex(pwd);
    }

    /**
     * 解密前台传入密码(先base64解密再rsa解密)
     *
     * @return
     */
    public static String staticDecryptPwd(String pwd) {
        try {
            Props props = new Props("rsa-key.properties");
            RSA rsa = SecureUtil.rsa(props.getProperty("privatekey"), props.getProperty("publickey"));
            pwd = new String(rsa.decrypt(Base64.decode(pwd), KeyType.PrivateKey));// base64解密再rsa解密
            return pwd;
        } catch (Exception e) {
            e.printStackTrace();
            throw new BussinessException("密码解析失败");
        }
    }

    /**
     * 密码加密(用于保存)
     *
     * @param pwd
     * @return
     */
    public static String staticEncodePwd(String pwd) {
        return DigestUtil.md5Hex(pwd);
    }
}
